home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
cuj0696.zip
/
DWYER.ZIP
/
QFLOAT
/
QREMAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-31
|
2KB
|
112 lines
/*
This is borrowed from ieee.c, where it is used for radix conversion.
Hope the program didn't break in translation.
It would execute very slowly if numerator >> denominator.
Detecting whether n * a is exact could speed it up.
*/
/* Floating point remainder.
c = remainder after dividing b by a.
If n = integer part of b/a, rounded toward zero,
then qremain(a,b,c) gives c = b - n * a. */
#include "qhead.h"
#include "mconf.h"
extern QELT qzero[];
int normlz(), cmpm(), subm(), shdn1(), shup1(), shup16(), shup8(), mdnorm();
int qcmp(), qclear(), qmov();
static QELT quot[NQ+1];
int qremain( a, b, c )
QELT a[], b[], c[];
{
QELT den[NQ+1], num[NQ+1];
QELT j;
int i;
if( qcmp(a,qzero) == 0 )
{
mtherr( "qremain", SING );
qclear( c );
return 0;
}
den[NQ] = 0;
qmov( a, den );
den[0] = 0;
num[NQ] = 0;
qmov( b, num );
num[0] = 0;
/* Execute divide steps until num < den.
Least significant integer quotient bits left in quot[]. */
quot[NQ] = 0;
qclear( quot );
while( qcmp(num,den) >= 0 )
{
if( cmpm(den,num) <= 0 )
{
subm(den, num);
j = 1;
}
else
{
j = 0;
}
shup1(quot);
quot[NQ] |= j;
shup1(num);
num[1] -= 1;
}
/* Normalize. */
while( num[2] != 0 )
{
shdn1( num );
num[1] += 1;
}
i = 0;
do
{
if( num[3] & SIGNBIT )
goto normok;
#if WORDSIZE == 32
else if( (num[3] & 0xffff0000) == 0 )
#else
else if( num[3] == 0 )
#endif
{
shup16(num);
num[1] -= 16;
i += 16;
}
#if WORDSIZE == 32
else if( (num[3] & 0xff000000) == 0 )
#else
else if( num[3] & 0xff00 == 0 )
#endif
{
shup8(num);
num[1] -= 8;
i += 8;
}
else
{
shup1(num);
num[1] -= 1;
i += 1;
}
}
while( i<=NBITS );
qclear(num);
normok:
/* Sign of remainder = sign of dividend. */
*num = *b; /* Set sign of Remainder */
qmov( num, c );
return 0;
}